
      
<h1 class="mume-header" id="webhooks%E5%AE%9E%E8%B7%B5go%E8%AF%AD%E8%A8%80">Webhooks&#x5B9E;&#x8DF5;(Go&#x8BED;&#x8A00;)</h1>

<p>&#x9879;&#x76EE;&#x9700;&#x8981;&#xFF0C;&#x767E;&#x5EA6;&#x4E86;&#x4E00;&#x4E0B;Github Webhooks&#xFF0C;&#x5185;&#x5BB9;&#x57FA;&#x672C;&#x96F7;&#x540C;&#xFF0C;&#x4E5F;&#x6CA1;&#x6709;&#x627E;&#x5230;&#x6211;&#x60F3;&#x8981;&#x7684;&#x5982;&#x4E0B;&#x4E24;&#x4E2A;&#x529F;&#x80FD;&#x8BF4;&#x660E;&#xFF1A;</p>
<ul>
<li>&#x63D0;&#x4EA4;&#x65F6;&#x505A;&#x4E86;&#x54EA;&#x4E9B;&#x53D8;&#x52A8;&#xFF1F;</li>
<li>secret&#x7684;&#x4F7F;&#x7528;</li>
</ul>
<p>&#x7F62;&#x4E86;&#xFF0C;&#x60F3;&#x62FF;&#x6765;&#x5373;&#x7528;&#x7684;&#x5077;&#x61D2;&#x4E4B;&#x8DEF;&#x8D70;&#x4E0D;&#x901A;&#xFF0C;&#x53EA;&#x80FD;&#x8001;&#x8001;&#x5B9E;&#x5B9E;&#x5543;<a href="https://developer.github.com/webhooks/">&#x5B98;&#x65B9;&#x6587;&#x6863;</a>&#x4E86;&#x3002;</p>
<h3 class="mume-header" id="webhooks%E5%B9%B2%E5%98%9B%E7%94%A8%E7%9A%84">Webhooks&#x5E72;&#x561B;&#x7528;&#x7684;&#xFF1F;</h3>

<p>Github Webhooks&#x63D0;&#x4F9B;&#x4E86;&#x4E00;&#x5806;&#x4E8B;&#x4EF6;&#xFF0C;&#x8FD9;&#x4E9B;&#x4E8B;&#x4EF6;&#x5728;&#x7528;&#x6237;&#x7279;&#x5B9A;&#x7684;&#x64CD;&#x4F5C;&#x4E0B;&#x4F1A;&#x88AB;&#x89E6;&#x53D1;&#xFF0C;&#x6BD4;&#x5982;&#x521B;&#x5EFA;&#x5206;&#x652F;(Branch)&#x3001;&#x5E93;&#x88AB;fork&#x3001;&#x9879;&#x76EE;&#x88AB;star&#x3001;&#x7528;&#x6237;push&#x4E86;&#x4EE3;&#x7801;&#x7B49;&#x7B49;&#x3002;<br>
&#x6211;&#x4EEC;&#x53EF;&#x4EE5;&#x81EA;&#x5DF1;&#x5199;&#x4E00;&#x4E2A;&#x670D;&#x52A1;,&#x5C06;&#x670D;&#x52A1;&#x7684;URL&#x4EA4;&#x7ED9;Webhooks&#xFF0C;&#x5F53;&#x4E0A;&#x8FF0;&#x4E8B;&#x4EF6;&#x88AB;&#x89E6;&#x53D1;&#x65F6;&#xFF0C;Webhook&#x4F1A;&#x5411;&#x8FD9;&#x4E2A;&#x670D;&#x52A1;&#x53D1;&#x9001;&#x4E00;&#x4E2A;POST&#x8BF7;&#x6C42;&#xFF0C;&#x8BF7;&#x6C42;&#x4E2D;&#x9644;&#x5E26;&#x7740;&#x8BE5;&#x4E8B;&#x4EF6;&#x76F8;&#x5173;&#x7684;&#x8BE6;&#x7EC6;&#x63CF;&#x8FF0;&#x4FE1;&#x606F;(&#x5373;Payload)&#x3002;<br>
&#x8FD9;&#x6837;&#xFF0C;&#x6211;&#x4EEC;&#x5C31;&#x53EF;&#x4EE5;&#x5728;&#x81EA;&#x5DF1;&#x670D;&#x52A1;&#x4E2D;&#x77E5;&#x9053;Github&#x7684;&#x4EC0;&#x4E48;&#x4E8B;&#x4EF6;&#x88AB;&#x89E6;&#x53D1;&#x4E86;&#xFF0C;&#x4E8B;&#x4EF6;&#x7684;&#x5185;&#x5BB9;&#x662F;&#x4EC0;&#x4E48;&#xFF1F;&#x636E;&#x6B64;&#x6211;&#x4EEC;&#x5C31;&#x53EF;&#x4EE5;&#x5E72;&#x4E00;&#x4E9B;&#x81EA;&#x5DF1;&#x60F3;&#x5E72;&#x7684;&#x4E8B;&#x4E86;&#x3002;&#x80FD;&#x5E72;&#x4EC0;&#x4E48;&#x5462;&#xFF1F;&#x5B98;&#x65B9;&#x8BF4;<code>You&apos;re only limited by your imagination</code>&#xFF0C;&#x5C31;&#x662F;&#x8BF4;&#x60F3;&#x5E72;&#x4EC0;&#x4E48;&#x90FD;&#x884C;&#xFF0C;&#x5C31;&#x770B;&#x4F60;&#x7684;&#x60F3;&#x50CF;&#x529B;&#x591F;&#x4E0D;&#x591F; &#x1F603;</p>
<h3 class="mume-header" id="webhooks%E9%85%8D%E7%BD%AE">Webhooks&#x914D;&#x7F6E;</h3>

<p>&#x8FDB;&#x5165;&#x8981;hook&#x7684;&#x5E93;--&gt;Settings--&gt;Webhooks--&gt;Add Webhook<br>
<img src="/images/add-webhooks.png" alt="add webhooks"><br>
Add Webhook&#x754C;&#x9762;&#x957F;&#x8FD9;&#x6837;&#xFF1A;<br>
<img src="/images/add-webhooks2.png" alt="add webhooks"></p>
<ul>
<li>
<p>Payload URL<br>
&#x5C31;&#x662F;&#x6211;&#x4EEC;&#x7528;&#x6765;&#x63A5;&#x6536;&#x4E8B;&#x4EF6;&#x8BE6;&#x60C5;(Payload)&#x7684;&#x670D;&#x52A1;URL</p>
</li>
<li>
<p>Content type<br>
&#x5373;Webhooks&#x7528;&#x4EC0;&#x4E48;&#x6837;&#x7684;&#x6570;&#x636E;&#x683C;&#x5F0F;&#x7ED9;&#x6211;&#x4EEC;&#x53D1;&#x9001;Payload,Webhooks&#x652F;&#x6301;&#x4EE5;&#x4E0B;&#x4E24;&#x79CD;&#x7C7B;&#x578B;&#x7684;&#x6570;&#x636E;</p>
<ul>
<li>application/json</li>
<li>application/x-www-form-urlencoded</li>
</ul>
</li>
<li>
<p>Secret<br>
&#x8FD9;&#x91CC;&#x53EF;&#x4EE5;&#x63D0;&#x4F9B;&#x4E00;&#x4E2A;&#x52A0;&#x5BC6;Key,Webhooks&#x4F1A;&#x4EE5;&#x6B64;key&#x751F;&#x6210;Payload&#x7684;&#x4E00;&#x4E2A;&#x6570;&#x5B57;&#x7B7E;&#x540D;&#x968F;POST&#x8BF7;&#x6C42;&#x53D1;&#x9001;&#x7ED9;&#x4F60;&#xFF0C;&#x4F60;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;&#x6B64;&#x7B7E;&#x540D;&#x9A8C;&#x8BC1;&#x6570;&#x636E;&#x7684;&#x5408;&#x6CD5;&#x6027;&#x3002;&#x5982;&#x4F55;&#x9A8C;&#x8BC1;&#xFF0C;&#x89C1;&#x540E;&#x6587;&#x6240;&#x9644;&#x4EE3;&#x7801;&#x3002;</p>
</li>
<li>
<p>Webhook event<br>
Webhooks&#x4E8B;&#x4EF6;&#x7684;&#x9009;&#x62E9;&#x9879;:</p>
<ul>
<li>Just the push event<br>
&#x4EC5;hook Push&#x4E8B;&#x4EF6;</li>
<li>Send me everything<br>
hook&#x6240;&#x6709;&#x4E8B;&#x4EF6;</li>
<li>Let me select indiidual event<br>
&#x8BA9;&#x7528;&#x6237;&#x81EA;&#x5DF1;&#x9009;&#x62E9;hook&#x4EC0;&#x4E48;&#x4E8B;&#x4EF6;</li>
</ul>
<p>&#x9ED8;&#x8BA4;&#x662F;<code>Just the push event.</code>,&#x6211;&#x4EEC;&#x4E0D;&#x6539;&#x4E86;&#xFF0C;&#x7528;&#x5B83;&#x5F97;&#x4E86;&#x3002;</p>
</li>
</ul>
<h3 class="mume-header" id="post%E4%BA%86%E4%BB%80%E4%B9%88%E4%B8%9C%E4%B8%9C">Post&#x4E86;&#x4EC0;&#x4E48;&#x4E1C;&#x4E1C;</h3>

<p>&#x5728;&#x5199;&#x670D;&#x52A1;&#x4E4B;&#x524D;&#xFF0C;&#x6211;&#x4EEC;&#x5148;&#x770B;&#x770B;Webhooks&#x7ED9;&#x6211;&#x4EEC;&#x53D1;&#x9001;&#x4E86;&#x4EC0;&#x4E48;&#x3002;</p>
<ul>
<li>Post Request Header<br>
<img src="/images/webhooks-request-headers.png" alt="Post Request Header">
<ul>
<li>Request URL<br>
&#x5373;&#x524D;&#x9762;&#x914D;&#x7F6E;&#x4E2D;&#x586B;&#x5199;&#x7684;&#x201C;Payload URL&#x201D;</li>
<li>content-type<br>
&#x5373;&#x524D;&#x9762;&#x914D;&#x7F6E;&#x4E2D;&#x9009;&#x62E9;&#x7684;&#x201C;Content type&#x201D;</li>
<li>X-Hub-Signature<br>
&#x662F;&#x5BF9;Payload&#x8BA1;&#x7B97;&#x5F97;&#x51FA;&#x7684;&#x7B7E;&#x540D;&#x3002;&#x5F53;&#x6211;&#x4EEC;&#x5728;&#x524D;&#x9762;&#x7684;&#x914D;&#x7F6E;&#x4E2D;&#x8F93;&#x5165;&#x4E86;&#x201C;Secret&#x201D;&#x540E;&#xFF0C;Header&#x4E2D;&#x624D;&#x4F1A;&#x51FA;&#x73B0;&#x6B64;&#x9879;&#x3002;<a href="https://developer.github.com/webhooks/securing/">&#x5B98;&#x65B9;&#x6587;&#x6863;</a>&#x5BF9;Secret&#x4F5C;&#x4E86;&#x8BE6;&#x7EC6;&#x8BF4;&#x660E;&#xFF0C;&#x540E;&#x9762;&#x6211;&#x4EEC;&#x4E5F;&#x4F1A;&#x5728;&#x4EE3;&#x7801;&#x4E2D;&#x5B9E;&#x73B0;&#x5BF9;&#x5B83;&#x7684;&#x6821;&#x9A8C;&#x3002;</li>
</ul>
</li>
<li>Post Request Body<br>
<img src="/images/webhooks-request-payload.png" alt="Post Request Body"><br>
&#x8FD9;&#x662F;&#x89E6;&#x53D1;Push&#x4E8B;&#x4EF6;&#x65F6;Webhooks&#x53D1;&#x7ED9;&#x6211;&#x4EEC;&#x7684;Payload,&#x84DD;&#x8272;&#x6846;&#x4E2D;&#x7684;&#x5185;&#x5BB9;&#x5C31;&#x662F;&#x6211;&#x671F;&#x671B;&#x5F97;&#x5230;&#x7684;&#x5E93;&#x6587;&#x4EF6;&#x7684;&#x53D8;&#x52A8;&#x4FE1;&#x606F;&#x3002;&#x5F88;&#x76F4;&#x767D;&#xFF0C;&#x4E0D;&#x518D;&#x89E3;&#x91CA;&#x3002;&#x6709;&#x4E86;&#x6570;&#x636E;&#x7ED3;&#x6784;&#xFF0C;&#x62FF;&#x5230;&#x60F3;&#x8981;&#x7684;&#x6570;&#x636E;&#x5C31;&#x4E0D;&#x662F;&#x96BE;&#x4E8B;&#x4E86;&#xFF0C;&#x6240;&#x4EE5;&#x540E;&#x9762;&#x4EE3;&#x7801;&#x4E2D;&#x4E5F;&#x4E0D;&#x4F1A;&#x6709;&#x8FD9;&#x90E8;&#x5206;&#x5185;&#x5BB9;&#x4E86;&#x3002;</li>
</ul>
<h3 class="mume-header" id="%E6%88%91%E4%BB%AC%E7%9A%84%E6%9C%8D%E5%8A%A1%E6%80%8E%E4%B9%88%E5%86%99">&#x6211;&#x4EEC;&#x7684;&#x670D;&#x52A1;&#x600E;&#x4E48;&#x5199;&#xFF1F;</h3>

<p>&#x672C;&#x6587;&#x4E2D;&#x4F7F;&#x7528;Gin&#x5B9E;&#x73B0;&#x6240;&#x9700;&#x529F;&#x80FD;&#xFF0C;&#x4EE3;&#x7801;&#x4EC5;&#x7528;&#x4E8E;&#x6F14;&#x793A;&#xFF0C;&#x8BF7;&#x8F7B;&#x62CD; &#x1F603;</p>
<pre data-role="codeBlock" data-info="go" class="language-go"><span class="token keyword">func</span> <span class="token function">Init</span><span class="token punctuation">(</span>g <span class="token operator">*</span>gin<span class="token punctuation">.</span>Engine<span class="token punctuation">,</span> mw <span class="token operator">...</span>gin<span class="token punctuation">.</span>HandlerFunc<span class="token punctuation">)</span> <span class="token operator">*</span>gin<span class="token punctuation">.</span>Engine <span class="token punctuation">{</span>  
	<span class="token comment">// Middlewares.  </span>
	g<span class="token punctuation">.</span><span class="token function">Use</span><span class="token punctuation">(</span>mw<span class="token operator">...</span><span class="token punctuation">)</span>  

	<span class="token comment">// 404 &#x5904;&#x7406;  </span>
	g<span class="token punctuation">.</span><span class="token function">NoRoute</span><span class="token punctuation">(</span><span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">{</span>  
		c<span class="token punctuation">.</span><span class="token function">String</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusNotFound<span class="token punctuation">,</span> <span class="token string">&quot;The incorrect API route.&quot;</span><span class="token punctuation">)</span>  
	<span class="token punctuation">}</span><span class="token punctuation">)</span>  

	<span class="token comment">// &#x8DEF;&#x7531;  </span>
	sv <span class="token operator">:=</span> g<span class="token punctuation">.</span><span class="token function">Group</span><span class="token punctuation">(</span><span class="token string">&quot;/sv&quot;</span><span class="token punctuation">)</span>  
	<span class="token punctuation">{</span>  
		sv<span class="token punctuation">.</span><span class="token function">POST</span><span class="token punctuation">(</span><span class="token string">&quot;/gitpush&quot;</span><span class="token punctuation">,</span> gitpush<span class="token punctuation">)</span>  
		<span class="token comment">// &#x5176;&#x5B83;&#x8DEF;&#x7531;&#x5B9A;&#x4E49;......  </span>
	<span class="token punctuation">}</span>  

	<span class="token keyword">return</span> g  
<span class="token punctuation">}</span>  

<span class="token comment">// Github Webhooks Post&#x8BF7;&#x6C42;&#x5904;&#x7406;&#x51FD;&#x6570;  </span>
<span class="token keyword">func</span> <span class="token function">gitpush</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">{</span>  
	<span class="token comment">// &#x9A8C;&#x8BC1;&#x7B7E;&#x540D;  </span>
	<span class="token keyword">if</span> matched<span class="token punctuation">,</span> <span class="token boolean">_</span> <span class="token operator">:=</span> <span class="token function">verifySignature</span><span class="token punctuation">(</span>c<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token operator">!</span>matched <span class="token punctuation">{</span>  
		err <span class="token operator">:=</span> <span class="token string">&quot;Signatures didn&apos;t match!&quot;</span>  
		c<span class="token punctuation">.</span><span class="token function">String</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusForbidden<span class="token punctuation">,</span> err<span class="token punctuation">)</span>  
		fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span>err<span class="token punctuation">)</span>  
		<span class="token keyword">return</span>  
	<span class="token punctuation">}</span>  

	fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">&quot;Signatures is match! go!&quot;</span><span class="token punctuation">)</span>  

	<span class="token comment">// &#x4F60;&#x81EA;&#x5DF1;&#x7684;&#x4E1A;&#x52A1;&#x903B;&#x8F91;......  </span>

	c<span class="token punctuation">.</span><span class="token function">String</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusOK<span class="token punctuation">,</span> <span class="token string">&quot;OK&quot;</span><span class="token punctuation">)</span>  
<span class="token punctuation">}</span>  

<span class="token comment">// &#x9A8C;&#x8BC1;&#x7B7E;&#x540D;  </span>
<span class="token keyword">func</span> <span class="token function">verifySignature</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">(</span><span class="token builtin">bool</span><span class="token punctuation">,</span> <span class="token builtin">error</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>  
	payloadBody<span class="token punctuation">,</span> err <span class="token operator">:=</span> c<span class="token punctuation">.</span><span class="token function">GetRawData</span><span class="token punctuation">(</span><span class="token punctuation">)</span>  
	<span class="token keyword">if</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>  
		<span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">,</span> err  
	<span class="token punctuation">}</span>  

	<span class="token comment">// &#x83B7;&#x53D6;&#x8BF7;&#x6C42;&#x5934;&#x4E2D;&#x7684;&#x7B7E;&#x540D;&#x4FE1;&#x606F;  </span>
	hSignature <span class="token operator">:=</span> c<span class="token punctuation">.</span><span class="token function">GetHeader</span><span class="token punctuation">(</span><span class="token string">&quot;X-Hub-Signature&quot;</span><span class="token punctuation">)</span>  

	<span class="token comment">// &#x8BA1;&#x7B97;Payload&#x7B7E;&#x540D;  </span>
	signature <span class="token operator">:=</span> <span class="token function">hmacSha1</span><span class="token punctuation">(</span>payloadBody<span class="token punctuation">)</span>  

	<span class="token keyword">return</span> <span class="token punctuation">(</span>hSignature <span class="token operator">==</span> signature<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token boolean">nil</span>  

<span class="token punctuation">}</span>  

<span class="token comment">// hmac-sha1  </span>
<span class="token keyword">func</span> <span class="token function">hmacSha1</span><span class="token punctuation">(</span>payloadBody <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token builtin">byte</span><span class="token punctuation">)</span> <span class="token builtin">string</span> <span class="token punctuation">{</span>  
	h <span class="token operator">:=</span> hmac<span class="token punctuation">.</span><span class="token function">New</span><span class="token punctuation">(</span>sha1<span class="token punctuation">.</span>New<span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token function">byte</span><span class="token punctuation">(</span><span class="token string">&quot;Sbjylss38&quot;</span><span class="token punctuation">)</span><span class="token punctuation">)</span>  
	h<span class="token punctuation">.</span><span class="token function">Write</span><span class="token punctuation">(</span>payloadBody<span class="token punctuation">)</span>  
	<span class="token keyword">return</span> <span class="token string">&quot;sha1=&quot;</span> <span class="token operator">+</span> hex<span class="token punctuation">.</span><span class="token function">EncodeToString</span><span class="token punctuation">(</span>h<span class="token punctuation">.</span><span class="token function">Sum</span><span class="token punctuation">(</span><span class="token boolean">nil</span><span class="token punctuation">)</span><span class="token punctuation">)</span>  
<span class="token punctuation">}</span>  
</pre>
      